package session.stateful;

import entity.AddressEntity;

import entity.IndustryTypeEntity;

import entity.PaymentManagementEntity;
import entity.StakeholderEntity;

import java.util.Date;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import exception.StakeholderBizRegNumberExist;
import exception.StakeholderEmailExist;
import exception.StakeholderUsernameExist;
import javax.mail.internet.*;
import javax.mail.Authenticator;
import javax.mail.Session;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Transport;
import java.util.Properties;


@Stateful
@LocalBean
public class StakeholderSessionBeanStateful {

    @PersistenceContext
    private EntityManager entityManager;
    private String user;
    private String pwd;

    public List<StakeholderEntity> getStakeholders(String condition) {
        Query query = entityManager.createQuery(condition);
        return query.getResultList();
    }

    public List<String> getEmails() {
        System.out.print("Session Bean 1");
        Query query = entityManager.createQuery("SELECT s.corpEmail FROM StakeholderEntity s");
        System.out.print("Session Bean 2");
        return (List<String>) query.getResultList();
    }
    
    
    
    public List<String> getUsernames() {
        Query query = entityManager.createQuery("SELECT s.corpName FROM StakeholderEntity s");
        return (List<String>) query.getResultList();
    } 

    public void sendMail(String recipient, String subject, String message, String from) throws MessagingException {
        try {
            Properties props = new Properties();
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.host", "smtp.gmail.com");
            props.put("mail.smtp.auth", "true");

            // use your gmail account username here        
            props.put("mail.smtp.user", user);
            props.put("mail.smtp.port", "465");
            props.put("mail.mime.charset", "ISO-8859-1");
            props.put("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.socketFactory.fallback", "false");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");


            Authenticator auth = new PasswordAuthenticator();
            Session session = Session.getInstance(props, auth);
            session.setDebug(true);

            MimeMessage msg = new MimeMessage(session);

            msg.setFrom(new InternetAddress(from));

            InternetAddress[] address = {new InternetAddress(recipient)};
            msg.setRecipients(Message.RecipientType.TO, address);
            msg.setSubject(subject);
            msg.setText(message);

            Transport.send(msg);

        } catch (Exception mex) {
            mex.printStackTrace();
        }
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public StakeholderEntity getStakeholderById(long id) {
        return entityManager.find(StakeholderEntity.class, id);
    }

    private class PasswordAuthenticator extends javax.mail.Authenticator {
        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(getUser(), getPwd());
        }
    } 

    public void addNewStakeholder(StakeholderEntity stakeholderTemp, AddressEntity addressTemp, IndustryTypeEntity industryType) throws
            StakeholderBizRegNumberExist, StakeholderEmailExist, StakeholderUsernameExist {
        if (checkUsernameExist(stakeholderTemp.getUsername())) {
            throw new StakeholderUsernameExist("The username " + stakeholderTemp.getUsername() + " has already existed.");
        }

        if (checkEmailExist(stakeholderTemp.getCorpEmail())) {
            throw new StakeholderEmailExist("The email " + stakeholderTemp.getCorpEmail()+ " has already existed.");
        }
        if (checkBizRegNumberExist(stakeholderTemp.getBizRegNumber())) {
            throw new StakeholderBizRegNumberExist("The business registration number " + stakeholderTemp.getBizRegNumber() + " has already existed.");
        }
        AddressEntity address = new AddressEntity(addressTemp);
        entityManager.persist(address);
       
        StakeholderEntity stakeholder = new StakeholderEntity(stakeholderTemp);
        stakeholder.setAddress(address);
        // Added by Cong Dat
        stakeholder.setDateRegistered(new Date());
        entityManager.persist(stakeholder);
        
        stakeholder.setIndustry(industryType);
        industryType.getStakeholder().add(stakeholder);
        entityManager.merge(industryType);
    }

    public List<StakeholderEntity> getAllStakeholders() {
        Query query = entityManager.createQuery("SELECT s FROM StakeholderEntity s");
        return query.getResultList();
    }
    
    public void editStakeholderInfo(StakeholderEntity stakeholder) {      
        entityManager.merge(stakeholder);
    }

    private boolean checkUsernameExist(String username) {
        Query query = entityManager.createQuery("SELECT s FROM StakeholderEntity s WHERE s.username = :username");
        query.setParameter("username", username);
        List list = query.getResultList();

        if (list.isEmpty()) {
            return false;
        }

        return true;
    }

    private boolean checkEmailExist(String email) {
        Query query = entityManager.createQuery("SELECT s FROM StakeholderEntity s WHERE s.corpEmail = :email");
        query.setParameter("email", email);
        List list = query.getResultList();

        if (list.isEmpty()) {
            return false;
        }

        return true;
    }

    private boolean checkBizRegNumberExist(String bizRegNumber) {
        Query query = entityManager.createQuery("SELECT s FROM StakeholderEntity s WHERE s.bizRegNumber = :bizRegNumber");
        query.setParameter("bizRegNumber", bizRegNumber);
        List list = query.getResultList();

        if (list.isEmpty()) {
            return false;
        }

        return true;
    }

    public StakeholderEntity retrieveStakeholderInfoByUsername(String username) {
        Query query = entityManager.createQuery("SELECT s FROM StakeholderEntity s WHERE s.username = :username");
        query.setParameter("username", username);
        return (StakeholderEntity) query.getSingleResult();
    }

    public List<IndustryTypeEntity> getIndustryTypeList() {
        Query query = entityManager.createQuery("SELECT i FROM IndustryTypeEntity i");
        return query.getResultList();
    }
    
 // This method is added by Cong Dat
    public List<PaymentManagementEntity> getBillListByStakeholderId(Long stakeholderId) {
        StakeholderEntity stakeholder = entityManager.find(StakeholderEntity.class, stakeholderId);
        return stakeholder.getPaymentManagement();
    }
    
    public List<PaymentManagementEntity> getBillListOfAllStakeholders() {
        Query query = entityManager.createQuery("SELECT p FROM PaymentManagementEntity p");
        return query.getResultList();
    }


}
